using System;
using System.Linq;
using GatewayPattern.ServiceReferences.DummyData;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace GatewayPattern
{
    [TestClass]
    public class Gateway_pattern_1
    {
        [TestMethod]
        public void Getting_the_data_without_the_gateway()
        {
            using (var dummyDataClient = new DummyDataClient())
            {
                var dummies = dummyDataClient.FindAll();

                Assert.AreEqual(20, dummies.Length);
                Assert.AreEqual(dummies[0].Property1, "Property 1.1");
                Assert.AreEqual(dummies[19].Property2, "Property 20.2");
            }
        }
    }

    [TestClass]
    public class Gateway_pattern_2
    {
        [TestMethod]
        public void Getting_the_data_from_a_static_gateway()
        {
            var dummies = DummyDataGateway.FindAll();

            Assert.AreEqual(20, dummies.Length);
            Assert.AreEqual(dummies[0].Property1, "Property 1.1");
            Assert.AreEqual(dummies[19].Property2, "Property 20.2");
        }

        private static class DummyDataGateway
        {
            public static Dummy[] FindAll()
            {
                using (var dummyDataClient = new DummyDataClient())
                    return dummyDataClient.FindAll();
            }
        }
    }

    [TestClass]
    public class Gateway_pattern_3
    {
        [TestMethod]
        public void Getting_the_data_from_a_static_gateway_the_right_way()
        {
            var dummies = DummyDataGateway.FindAll();

            Assert.AreEqual(20, dummies.Length);
            Assert.AreEqual(dummies[0].PropertyOne, "Property 1.1");
            Assert.AreEqual(dummies[19].PropertyTwo, "Property 20.2");
        }

        private static class DummyDataGateway
        {
            // The right way means created your own DTOs along side your gateway
            public static DummyDataDummy[] FindAll()
            {
                using (var dummyDataClient = new DummyDataClient())
                    return dummyDataClient
                        .FindAll()
                        .Select(x => new DummyDataDummy {PropertyOne = x.Property1, PropertyTwo = x.Property2})
                        .ToArray();
            }
        }

        private class DummyDataDummy
        {
            public string PropertyOne { get; set; }
            public string PropertyTwo { get; set; }
        }
    }

    [TestClass]
    public class Gateway_pattern_4
    {
        [TestMethod]
        public void When_gateways_can_save_your_bacon()
        {
            IDummyDataGateway gateway = new DummyDataGatewayStub();

            var dummies = gateway.FindAll();

            Assert.AreEqual(10, dummies.Length);
            Assert.AreEqual(dummies[0].PropertyOne, "Property 1.1");
            Assert.AreEqual(dummies[9].PropertyTwo, "Property 10.2");
        }

        private interface IDummyDataGateway
        {
            DummyDataDummy[] FindAll();
        }

        private class DummyDataGateway : IDummyDataGateway
        {
            public DummyDataDummy[] FindAll()
            {
                using (var dummyDataClient = new DummyDataClient())
                    return dummyDataClient
                        .FindAll()
                        .Select(x => new DummyDataDummy {PropertyOne = x.Property1, PropertyTwo = x.Property2})
                        .ToArray();
            }
        }

        private class DummyDataGatewayStub : IDummyDataGateway
        {
            public DummyDataDummy[] FindAll()
            {
                return new[]
                    {
                        new DummyDataDummy {PropertyOne = "Property 1.1", PropertyTwo = "Property 1.2"},
                        new DummyDataDummy {PropertyOne = "Property 2.1", PropertyTwo = "Property 2.2"},
                        new DummyDataDummy {PropertyOne = "Property 3.1", PropertyTwo = "Property 3.2"},
                        new DummyDataDummy {PropertyOne = "Property 4.1", PropertyTwo = "Property 4.2"},
                        new DummyDataDummy {PropertyOne = "Property 5.1", PropertyTwo = "Property 5.2"},
                        new DummyDataDummy {PropertyOne = "Property 6.1", PropertyTwo = "Property 6.2"},
                        new DummyDataDummy {PropertyOne = "Property 7.1", PropertyTwo = "Property 7.2"},
                        new DummyDataDummy {PropertyOne = "Property 8.1", PropertyTwo = "Property 8.2"},
                        new DummyDataDummy {PropertyOne = "Property 9.1", PropertyTwo = "Property 9.2"},
                        new DummyDataDummy {PropertyOne = "Property 10.1", PropertyTwo = "Property 10.2"},
                    };
            }
        }

        private class DummyDataDummy
        {
            public string PropertyOne { get; set; }
            public string PropertyTwo { get; set; }
        }
    }
}